/**
 * Copyright (c) 2011 Nokia Corporation.
 */

// Own header
#include "DriveModel.h"

// QtMobility includes
#include <qsysteminfo.h>

// Backup2Go includes
#include "trace.h"

QTM_USE_NAMESPACE;


/*!
  \class DriveModel
  \brief A model for handling the available drives.
*/


/*!
  Constructor.
*/
DriveModel::DriveModel(QObject *parent /* = 0 */)
    : QAbstractListModel(parent)
{
    QHash<int, QByteArray> roles;
    roles[TypeRole] = "type";
    roles[VolumeRole] = "volume";
    roles[NameRole] = "name";
    setRoleNames(roles);
}


/*!
  Destructor.
*/
DriveModel::~DriveModel()
{
}


/*!
  From QAbstractListModel.
*/
QVariant DriveModel::data(const QModelIndex &index,
                          int role /* = Qt::DisplayRole */) const
{
    const int itemIndex(index.row());

    if (!index.isValid() || itemIndex >= m_filteredDrives.count()) {
        // Invalid index!
        DEBUG_INFO("Invalid index:" << itemIndex);
        return QVariant();
    }

    QVariant value = QVariant();

    switch (role) {
        case TypeRole: {
            value = QVariant::fromValue(m_filteredDrives[itemIndex].m_type);
            break;
        }
        case VolumeRole: {
            value = QVariant::fromValue(m_filteredDrives[itemIndex].m_vol);
            break;
        }
        case NameRole: {
            // Not implemented!
            break;
        }
    } // switch (role)

    return value;
}


/*!
  From QAbstractListModel.
*/
int DriveModel::rowCount(const QModelIndex &parent /* = QModelIndex() */) const
{
    Q_UNUSED(parent);
    return m_filteredDrives.count();
}


/*!
  From QAbstractListModel.
*/
void DriveModel::removeRow(int row, const QModelIndex &parent)
{
    if (0 > row && row > m_filteredDrives.count() - 1) {
        // Invalid row!
        return;
    }

    beginRemoveRows(QModelIndex(), row, row);
    m_filteredDrives.removeAt(row);
    endRemoveRows();
    emit rowCountChanged(rowCount());
}


/*!
  Appends \a driveInfo into the model.
*/
void DriveModel::appendDrive(DriveInfo &driveInfo)
{
    if (!m_allDrives.contains(driveInfo)) {
        m_allDrives.append(driveInfo);

#ifdef Q_OS_WIN
        DEBUG_INFO("Will not apply filtering in Windows.");
        appendFilteredDrive(driveInfo);
#else
        if (!m_filters.count() || m_filters.contains(driveInfo.m_type)) {
            appendFilteredDrive(driveInfo);
        }
#endif
    }
}


/*!
  Returns the drive volume as string by \a index or an empty string if not
  found.
*/
QString DriveModel::driveByIndex(int index) const
{
    QString driveVolume = QString();

    if (index >= 0 && index < m_filteredDrives.count()) {
        driveVolume = m_filteredDrives[index].m_vol;

        if (driveVolume.length() == 1) {
            // The drive volume seems to be a single letter. Append ":/" to the
            // end of the string.
            driveVolume.append(":/");
        }
    }

    return driveVolume;
}


/*!
  Sets \a filters to be used to filter out the type of drives.
*/
void DriveModel::setFilters(QList<int> &filters)
{
    m_filters = filters;
    refresh();
}


/*!
  For convenience.
*/
void DriveModel::filterRemovableDrivesOnly()
{
    DEBUG_POINT;
    setFilters(QList<int>() << QSystemStorageInfo::RemovableDrive);
}


/*!
  For convenience.
*/
void DriveModel::filterInternalDrivesOnly()
{
    DEBUG_POINT;
    setFilters(QList<int>() << QSystemStorageInfo::InternalDrive);
}


/*!
  Clears the model content. If \a allDrives is false, the private list
  containing all drives will not be cleared.
*/
void DriveModel::clear(bool allDrives /* = true */)
{
    if (allDrives) {
        DEBUG_INFO("Will clear m_allDrives, which contains" <<
                   m_allDrives.count() << "items.");
        m_allDrives.clear();
    }

    DEBUG_INFO("Will remove" << m_filteredDrives.count() <<
               "rows from m_filteredDrives.");
    while (!m_filteredDrives.empty()) {
        removeRow(m_filteredDrives.count() - 1, QModelIndex());
    }
}


/*!
  Refreshes the model content.
*/
void DriveModel::refresh()
{
    // Clear the filtered content.
    clear(false);

    DriveInfo info;
    QList<DriveInfo> tempList;

#ifdef Q_OS_WIN
    DEBUG_INFO("Will not apply filtering in Windows.");
    tempList = m_allDrives;
#else
    foreach (info, m_allDrives) {        
        if (!m_filters.count() || m_filters.contains(info.m_type)) {
            DEBUG_INFO("Appending" << info.m_vol);
            tempList.append(info);
        }
    }
#endif

    const int count(tempList.count());

    if (count) {
        beginInsertRows(QModelIndex(), 0, count - 1);
        m_filteredDrives = tempList;
        endInsertRows();
        emit rowCountChanged(rowCount());
    }
}


/*!
  Appends \a driveInfo into the model.
*/
void DriveModel::appendFilteredDrive(DriveInfo &driveInfo)
{
    if (!m_filteredDrives.contains(driveInfo)) {
        int row(m_filteredDrives.count());
        beginInsertRows(QModelIndex(), row + 1, row + 1);
        m_filteredDrives.append(driveInfo);
        endInsertRows();
        emit rowCountChanged(rowCount());
    }
}


// End of file.
